package server

import (
	"fmt"
	"log"
	"math/rand"
	"net"
	"syproxy/library"
	"syproxy/service"
	"time"
)

func Run(l, r, authWd string) {
	localListener, _ := net.Listen("tcp", l)
	remoteListener, _ := net.Listen("tcp", r)
	container := library.NewContainer()

	log.Println("Server start！")
	for {
		// 等待客户端建立长时间的tcp连接
		local := service.NewService()
		local.Conn, _ = localListener.Accept()
		local.Id = generNum()
		log.Printf("Client accept success, id: %v", local.Id)

		// 验证客户端身份
		err := service.AuthClient(local, authWd)
		if err != nil {
			log.Print(err)
			continue
		}

		go local.Read()
		go handleClient(local, container)

		for {
			// 等待远程调用
			remote := service.NewService()
			// 创建id
			remote.Id = generNum()
			var err error
			remote.Conn, err = remoteListener.Accept()
			if err != nil {
				log.Printf("Remote accept failed: remoteId: %v", remote.Id)
			}
			log.Printf("Remote accept success, id: %v", remote.Id)

			local.Write([]byte("open"), []byte(remote.Id))
			container.Push(remote.Id, remote)
			time.Sleep(time.Duration(20) * time.Millisecond)
			go remote.ReadRaw()
			go handle(remote, local, container)
		}
	}
}

// 处理与客户端交互
func handleClient(c *service.Service, container *library.Container) {
	for {
		select {
		case content := <-c.Recv:
			id := content.Id
			remote := container.GetService(id)
			library.HandleRead(content, c, remote)
		case <-c.CloseMe:
			// TODO:: 关闭所有的连接
			c.Close()
			container.RemoveAll()
			return
		case id := <-c.CloseOther:
			remote := container.GetService(id)
			container.Remove(id)
			remote.Close()
		}
	}
}

// 处理交互
func handle(s, c *service.Service, container *library.Container) {
	for {
		select {
		case content := <-s.Recv:
			c.Write(content.Data, []byte(s.Id))
		case <-s.CloseMe:
			container.Remove(s.Id)
			s.Close()
			c.Write([]byte("close"), []byte(s.Id))
			return
		}
	}
}

func generNum() string {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))

	return fmt.Sprintf("%d", r.Int())
}
